package com.zn.opit.tech.easyexcel.utils;

import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.event.AnalysisEventListener;
import com.alibaba.excel.exception.ExcelAnalysisException;
import com.alibaba.fastjson.JSON;
import lombok.extern.slf4j.Slf4j;

import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

@Slf4j
public class ExcelListener<T> extends AnalysisEventListener<T> {
    /**
     * 可以通过实例获取该值
     */
    private List<T> dataList = new ArrayList<>();

    /**
     * 表头map（单行表头），列号-->列名
     */
    private Map<Integer, String> headMap = new LinkedHashMap<>();

    /**
     * 读取行数最大值（含表头）<br>
     * limit: -1 默认 不限制 <br>
     *        0  不限制    <br>
     *        n  限制行数   <br>
     */
    private int limit = -1;

    public ExcelListener() {
    }

    public ExcelListener(int limit) {
        this.limit = limit;
    }

    @Override
    public void invokeHeadMap(Map<Integer, String> headMap, AnalysisContext context) {
        this.headMap.putAll(headMap);
    }

    @Override
    public void invoke(T object, AnalysisContext context) {
        Integer rowNumber = context.readSheetHolder().getApproximateTotalRowNumber();

        if (this.limit > 0 && rowNumber > this.limit) {
            throw new ExcelAnalysisException("导入数据内容超出总行数["+this.limit+"]条限制" );
        }
        //数据存储到list，供批量处理，或后续自己业务逻辑处理。
        log.info("解析到一条数据:{}", JSON.toJSONString(object));
        dataList.add(object);
    }

    @Override
    public void doAfterAllAnalysed(AnalysisContext context) {
        //非必要语句，查看导入的数据
        System.out.println("导入的数据条数为: " + dataList.size());
    }

    /************************************** get && set ***********************************************************/

    public List<T> getDataList() {
        return dataList;
    }

    public void setDataList(List<T> dataList) {
        this.dataList = dataList;
    }

    public Map<Integer, String> getHeadMap() {
        return headMap;
    }

    public void setHeadMap(Map<Integer, String> headMap) {
        this.headMap = headMap;
    }
}
